import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

///控件滚动监听
class ScrollControllerTestRoute extends StatefulWidget {
  @override
  ScrollControllerTestRouteState createState() {
    return ScrollControllerTestRouteState();
  }
}

class ScrollControllerTestRouteState extends State<ScrollControllerTestRoute> {
  ScrollController _controller = ScrollController();
  bool showToTopBtn = false; //是否显示“返回到顶部”按钮

  @override
  void initState() {
    super.initState();
    //监听滚动事件，打印滚动位置
    _controller.addListener(() {
      print(_controller.offset); //打印滚动位置
      print("多个用法 ${_controller.positions.elementAt(0)}"); //打印滚动位置

      if (_controller.offset < 1000 && showToTopBtn) {
        setState(() {
          showToTopBtn = false;
        });
      } else if (_controller.offset >= 1000 && showToTopBtn == false) {
        setState(() {
          showToTopBtn = true;
        });
      }
    });

    /// ScrollPosition scrollPosition = ScrollPosition(,context: context)
  }

  @override
  void dispose() {
    //为了避免内存泄露，需要调用_controller.dispose
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    ///不同的item样式文案不同
    String selectContent(int index) {
      var content = "";
      if (index == 0) {
        content = "AnimatedList控件查看$index";
      } else if (index == 1) {
        content = "gridview控件查看$index";
      } else {
        content = "$index";
      }
      return content;
    }

    ///不同的item样式文案不同，点击效果不同
    void jumpTo(int index) {
      ///AnimatedList 和 ListView 的功能大体相似，不同的是， AnimatedList
      ///可以在列表中插入或删除节点时执行一个动画，在需要添加或删除列表项的场景中会提高用户体验。
      if (index == 0) {
        Navigator.push(context, MaterialPageRoute(builder: (context) {
          return AnimatedListRoute();
        }));
      } else if (index == 1) {
        Navigator.push(context, MaterialPageRoute(builder: (context) {
          return InfiniteGridView();
        }));
      }
    }

    return Scaffold(
      appBar: AppBar(title: Text("滚动控制")),
      body: Scrollbar(
        child: ListView.builder(
            itemCount: 100,
            itemExtent: 50.0, //列表项高度固定时，显式指定高度是一个好习惯(性能消耗小)
            controller: _controller,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text("${selectContent(index)}"),
                onTap: () {
                  jumpTo(index);
                },
              );
            }),
      ),
      floatingActionButton: !showToTopBtn
          ? null
          : FloatingActionButton(
              child: Icon(Icons.arrow_upward),
              onPressed: () {
                //返回到顶部时执行动画
                _controller.animateTo(
                  .0,
                  duration: Duration(milliseconds: 2000),
                  curve: Curves.ease,
                );

                ///Flutter Widget树中子Widget可以通过发送通知（Notification）与父(包括祖先)Widget通信
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return ScrollNotificationTestRoute();
                }));
              }),
    );
  }
}

///使用通知监听滑动
class ScrollNotificationTestRoute extends StatefulWidget {
  @override
  _ScrollNotificationTestRouteState createState() =>
      _ScrollNotificationTestRouteState();
}

class _ScrollNotificationTestRouteState
    extends State<ScrollNotificationTestRoute> {
  String _progress = "0%"; //保存进度百分比

  @override
  Widget build(BuildContext context) {
    return Scrollbar(
      //进度条
      // 监听滚动通知
      ///pixels：当前滚动位置。
      /// maxScrollExtent：最大可滚动长度。
      /// extentBefore：滑出ViewPort顶部的长度；此示例中相当于顶部滑出屏幕上方的列表长度。
      /// extentInside：ViewPort内部长度；此示例中屏幕显示的列表部分的长度。
      /// extentAfter：列表中未滑入ViewPort部分的长度；此示例中列表底部未显示到屏幕范围部分的长度。
      /// atEdge：是否滑到了可滚动组件的边界（此示例中相当于列表顶或底部）。
      child: NotificationListener<ScrollNotification>(
        onNotification: (ScrollNotification notification) {
          print("BottomEdge当前滚动位置pixels: ${notification.metrics.pixels} "
              "[像素]的最大范围内值maxScrollExtent:${notification.metrics.maxScrollExtent}");
          double progress = notification.metrics.pixels /
              notification.metrics.maxScrollExtent;
          //重新构建
          setState(() {
            _progress = "${(progress * 100).toInt()}%";
          });
          print("BottomEdge 列表中未滑入ViewPort部分的长度；此示例中列表底部未显示到屏幕范围部分的长度。"
              ": ${notification.metrics.extentAfter == 0}");
          return false;
          // return true; //放开此行注释后，进度条将失效
        },
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            ListView.builder(
              itemCount: 100,
              itemExtent: 50.0,
              itemBuilder: (context, index) => Text("$index"),
            ),
            CircleAvatar(
              //显示进度百分比
              radius: 30.0,
              child: Text(_progress),
              backgroundColor: Colors.black54,
            )
          ],
        ),
      ),
    );
  }
}

///item 添加移除动画
class AnimatedListRoute extends StatefulWidget {
  const AnimatedListRoute({Key? key}) : super(key: key);

  @override
  _AnimatedListRouteState createState() => _AnimatedListRouteState();
}

class _AnimatedListRouteState extends State<AnimatedListRoute> {
  var data = <String>[];
  int counter = 5;

  final globalKey = GlobalKey<AnimatedListState>();

  @override
  void initState() {
    for (var i = 0; i < counter; i++) {
      data.add('${i + 1}');
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
      children: [
        AnimatedList(
          key: globalKey,
          scrollDirection: Axis.vertical,
          initialItemCount: data.length,
          itemBuilder: (
            BuildContext context,
            int index,
            Animation<double> animation,
          ) {
            //添加列表项时会执行渐显动画
            return FadeTransition(
              opacity: animation,
              child: buildItem(context, index),
            );
          },
        ),
        buildAddBtn(),
      ],
    ));
  }

  // 创建一个 “+” 按钮，点击后会向列表中插入一项
  Widget buildAddBtn() {
    return Positioned(
      child: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          // setState(() {
          //   // 添加一个列表项
          //   data.add('${++counter}');
          //   });
          data.add('${++counter}');
          // 告诉列表项有新添加的列表项
          globalKey.currentState!.insertItem(data.length - 1);
          print('添加 $counter');
        },
      ),
      bottom: 30,
      left: 0,
      right: 0,
    );
  }

  // 构建列表项
  Widget buildItem(context, index) {
    String char = data[index];
    return ListTile(
      //数字不会重复，所以作为Key
      key: ValueKey(char),
      title: Text(char),
      trailing: IconButton(
        icon: Icon(Icons.delete),
        // 点击时删除
        onPressed: () => onDelete(context, index),
      ),
    );
  }

  void onDelete(context, index) {
    // 待实现
    // setState(() {
    globalKey.currentState!.removeItem(
      index,
      (context, animation) {
        // 删除过程执行的是反向动画，animation.value 会从1变为0
        var item = buildItem(context, index);
        print('删除 ${data[index]}');
        data.removeAt(index);
        // 删除动画是一个合成动画：渐隐 + 缩小列表项告诉
        return FadeTransition(
          opacity: CurvedAnimation(
            parent: animation,
            //让透明度变化的更快一些
            curve: const Interval(0.5, 1.0),
          ),
          // 不断缩小列表项的高度
          child: SizeTransition(
            sizeFactor: animation,
            axisAlignment: 0.0,
            child: item,
          ),
        );
      },
      duration: Duration(milliseconds: 2000), // 动画时间为 200 ms
    );
    // });
    print('移除 $index');
  }
}

///GridView 控件使用
class InfiniteGridView extends StatefulWidget {
  @override
  _InfiniteGridViewState createState() => _InfiniteGridViewState();
}

class _InfiniteGridViewState extends State<InfiniteGridView> {
  List<IconData> _icons = []; //保存Icon数据

  Widget _lodingWidget = Container(
    padding: const EdgeInsets.all(16.0),
    alignment: Alignment.center,
    child: SizedBox(
      width: 24.0,
      height: 24.0,
      child: CircularProgressIndicator(strokeWidth: 2.0),
    ),
  );

  var isShow = true;

  //通过key管理下拉刷新控件的显示隐藏，因为在当前控件调用，显示隐藏会导致整体混乱（指的是我当前的做法）
  GlobalKey<TextWidgetState> textKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    // 初始化数据
    _lodingWidget = Container(
      padding: const EdgeInsets.all(16.0),
      alignment: Alignment.center,
      child: SizedBox(
        width: 24.0,
        height: 24.0,
        child: CircularProgressIndicator(strokeWidth: 2.0),
      ),
    );
    _retrieveIcons();
  }

  void isShowLoadingWidget(bool isShow) {
    Future.delayed(Duration(milliseconds: 200)).then((e) {
      setState(() {
        if (isShow) {
          _lodingWidget = Container(
            padding: const EdgeInsets.all(16.0),
            alignment: Alignment.center,
            child: SizedBox(
              width: 24.0,
              height: 24.0,
              child: CircularProgressIndicator(strokeWidth: 2.0),
            ),
          );
        } else {
          _lodingWidget = Container(height: 0.0, width: 0.0);
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        color: Color(0xFFDB0987),
        // child: SingleChildScrollView(
        //     child: Column(
        //   children: [
        //     GridView.builder(
        //       shrinkWrap: true,
        //       gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        //         crossAxisCount: 3, //每行三列
        //         childAspectRatio: 1.0, //显示区域宽高相等
        //       ),
        //       itemCount: _icons.length,
        //       itemBuilder: (context, index) {
        //         //如果显示到最后一个并且Icon总数小于200时继续获取数据
        //         if (index == _icons.length - 1 && _icons.length < 200) {
        //           _retrieveIcons();
        //         }
        //         isShowLoadingWidget(
        //             index == _icons.length - 1 && _icons.length < 200);
        //         return Icon(_icons[index]);
        //       },
        //     ),
        //     _lodingWidget
        //   ],
        // )));

        child: Column(
          children: [
            Flexible(
              flex: 1,
              child: GridView.builder(
                shrinkWrap: false,
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3, //每行三列
                  childAspectRatio: 1.0, //显示区域宽高相等
                ),
                itemCount: _icons.length,
                itemBuilder: (context, index) {
                  // isShowLoadingWidget((((index + 1) / 3)%4==0));
                  //如果显示到最后一个并且Icon总数小于200时继续获取数据
                  // print("${_icons.length}--下标$index--判断标准：${(((index + 1) / 3)%4==0) && _icons.length < 50}");
                  print("${_icons.length}--下标$index");
                  if (index == _icons.length - 1 && _icons.length < 50) {
                    textKey.currentState!.onPressed(true);
                    _retrieveIcons();
                  } else {
                    // isShowLoadingWidget(false);
                    textKey.currentState!.onPressed(false);
                  }

                  return Text("$index");
                },
              ),
            ),
            ShowTextWidget(textKey),
          ],
        ));

    // child: GridView.builder(
    //   gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    //     crossAxisCount: 3, //每行三列
    //     childAspectRatio: 1.0, //显示区域宽高相等
    //   ),
    //   itemCount: _icons.length,
    //   itemBuilder: (context, index) {
    //     //如果显示到最后一个并且Icon总数小于200时继续获取数据
    //     if (index == _icons.length - 1 && _icons.length < 50) {
    //       print("${_icons.length}--下标$index--判断标准：${(((index + 1) / 3)%4==0) && _icons.length < 50}");
    //       _retrieveIcons();
    //     }
    //     return Icon(_icons[index]);
    //   },
    // ),
    // );
  }

  //模拟异步获取数据
  void _retrieveIcons() {
    Future.delayed(Duration(milliseconds: 2000)).then((e) {
      setState(() {
        _icons.addAll([
          Icons.ac_unit,
          Icons.airport_shuttle,
          Icons.all_inclusive,
          Icons.beach_access,
          Icons.cake,
          Icons.free_breakfast,
          Icons.ac_unit,
          Icons.airport_shuttle,
          Icons.all_inclusive,
          Icons.beach_access,
          Icons.cake,
          Icons.free_breakfast_sharp,
        ]);
      });
    });
  }
}

class ShowTextWidget extends StatefulWidget {
  //! 接收传过来的key
  ShowTextWidget(Key key) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return TextWidgetState();
  }
}

class TextWidgetState extends State<ShowTextWidget> {
  bool isShow = true;

  Widget _lodingWidget = Container(
    padding: const EdgeInsets.all(16.0),
    alignment: Alignment.center,
    child: SizedBox(
      width: 24.0,
      height: 24.0,
      child: CircularProgressIndicator(strokeWidth: 2.0),
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Visibility(
      visible: isShow,
      child: _lodingWidget,
    );
  }

  void onPressed(bool isShow) async {
    Future.delayed(Duration(milliseconds: 200)).then((e) {
      setState(() {
        this.isShow = isShow;
      });
    });
  }
}
